<?php

namespace common\observer;

use common\service\EntityService;
use think\module\Module;
use support\SingletonTrait;
use common\service\CommonService;
use teamones\dbeventObserver\interfaces\SplSubject;
use teamones\dbeventObserver\interfaces\SplObserver;
use Throwable;

/**
 * 修改了剧集、场次、角色类型，并且发布后，
 * 外包和集团公司处的任务也应修改这些信息
 */
class EntityChangeSyncToOutSourceEntity implements SplObserver
{
    use SingletonTrait;

    public $syncFields = [
        'initial_episode_code',
        'showings_number',
        'asset_perform_species',
        'remark',
        'name',
        'director_star',
        'key_shot',
        'is_confirm'
    ];

    protected $syncModuleCode = [
        'level',
        'asset',
        'shot',
    ];

    /**
     * @param SplSubject $subject
     * @return void
     */
    public function update(SplSubject $subject): void
    {
        $entity = $subject->getSubjectData();
        $updateData = $subject->getSplUpdateData();

        $module = module_by_id($entity['module_id']);
        if (!in_array($module['code'], $this->syncModuleCode)) {
            return;
        }
        $customFields = array_keys(Module::$moduleDictData['field_index_by_code'][$module['code']]['custom'] ?? []);
        // 求出变化的字段和要同步的字段的交集
        $changedFieldIntersect = array_intersect(array_merge($this->syncFields, $customFields), array_keys($updateData));
        if (empty($changedFieldIntersect)) {
            return;
        }
        // 查询外包实体
        $outsourceEntityList = EntityService::getInstance()->getOutsourceEntity($entity);
        if (empty($outsourceEntityList)) {
            return;
        }
        // 组装要更新的字段
        $syncData = [];
        $changedCustomFields = [];
        foreach ($changedFieldIntersect as $updateKey) {
            if ($updateKey === 'name') {
                // 保证名称修改 code不会重新生成
                $syncData['code'] = $entity['code'];
            }
            if (in_array($updateKey, $customFields)) {
                // 自定义字段 需要特殊处理
                $changedCustomFields[str_replace_once($module['code'], '', $updateKey)] = $updateData[$updateKey];
            } else {
                $syncData[$updateKey] = $updateData[$updateKey];
            }
        }

        foreach ($outsourceEntityList as $outsourceEntity) {
            try {
                $currentModule = module_by_id($outsourceEntity['module_id']);
                $tmpSyncData = $syncData;
                $tmpSyncData['id'] = $outsourceEntity['id'];
                // 把自定义字段修改为当前模块前缀
                foreach ($changedCustomFields as $k => $v) {
                    $tmpSyncData[$currentModule['code'] . $k] = $v;
                }
                // 预设好当前模块
                request()->getModuleCode($currentModule['code']);
                CommonService::instance('entity')
                    ->setCurrentModuleCode($currentModule['code'])
                    ->update($tmpSyncData, $currentModule['code'], false);
            } catch (Throwable $e) {
                trace(format_exception_info($e), 'ERR');
            }
        }
    }
}
